# 题目: 502. IPO

假设 力扣(LeetCode)即将开始 IPO 。为了以更高的价格将股票卖给风险投资公司,力扣 希望在 IPO 之前开展一些项目以增加其资本。 由于资源有限,它只能在 IPO 之前完成最多 k 个不同的项目。帮助 力扣 设计完成最多 k 个不同项目后得到最大总资本的方式。

给你 n 个项目。对于每个项目 i ,它都有一个纯利润 profits[i] ,和启动该项目需要的最小资本 capital[i]

最初,你的资本为 w 。当你完成一个项目时,你将获得纯利润,且利润将被添加到你的总资本中。

总而言之,从给定项目中选择 最多 k 个不同项目的列表,以 最大化最终资本 ,并输出最终可获得的最多资本。

答案保证在 32 位有符号整数范围内。

# 示例1:

输入:k = 2, w = 0, profits = [1,2,3], capital = [0,1,1]
输出:4
解释:
由于你的初始资本为 0,你仅可以从 0 号项目开始。
在完成后,你将获得 1 的利润,你的总资本将变为 1。
此时你可以选择开始 1 号或 2 号项目。
由于你最多可以选择两个项目,所以你需要完成 2 号项目以获得最大的资本。
因此,输出最后最大化的资本,为 0 + 1 + 3 = 4。

# 示例2:

输入:k = 3, w = 0, profits = [1,2,3], capital = [0,1,2]
输出:6

# 题解: 贪心算法

先设想,如果我们不限制次数的情况下,获取的做大利润是:

  • 将购入资本从小到大排序, 然后进行购买,并更新手中资本 w,直到最终无法购入项目或者没有项目为止。

现在有k个项目的限制,为了利润最大化:

  • 假设 w >= max(...capital), 则直接返回利润最大的k个项目。
  • 假设 w < max(...capital)
    • 找到 w > capital[n] 的元素, 并选择其中的最大利润
    • 更新掉 w, k--,继续重复。

# 代码

/**
 * @param {number} k
 * @param {number} w
 * @param {number[]} profits
 * @param {number[]} capital
 * @return {number}
 */
var findMaximizedCapital = function(k, w, profits, capital) {
    const maxCap = Math.max(...capital)
    let comObject = []
    for(let i=0;i<profits.length;i++){
        comObject.push({
            i:i,
            pro:profits[i],
            cap:capital[i]
        })
    }
    let res = w
    while(k){
        if(res >=maxCap){
            comObject.sort((a,b)=>b.pro-a.pro).slice(0,k).map(item => res+=item.pro)
            return res;
        }
        else{
            const temp = comObject.filter(item => item.cap <= res)
            if(temp.length === 0) return res
            else{
             const tempI = temp.sort((a,b)=>b.pro-a.pro)[0]
             comObject = comObject.filter(item => item.i!== tempI.i)
             res += tempI.pro
            }
            k--;
        }
    }
    return res
};

# 参考资料

  1. 502. IPO (opens new window)
  2. 官方题解 (opens new window)